
# used for saving files
require 'ftools'
require 'uuid'
require 'RMagick'
require 'net/smtp'

#
# some utilities for brad
#

class BaseUtils

    #########################################################################
    # save something; make thumbs if needed
    #########################################################################

    def BaseUtils.upload_path_base
      'files'
    end

    def BaseUtils.save_fuid
      return UUID.new
    end

    #
    # save a given parameter based file upload
    # 
    # optionally supply a target path, or else upload_path_base is used
    # 
    # optionally supply a target file name (do not include file extension mime)
    #
    def BaseUtils.save_file(command)
      return nil,nil if !command || !command[:blob] || !command[:site]
      blob = command[:blob]
      return nil,nil if !blob || !blob['tempfile'] || !blob['tempfile'].path
      site = command[:site]
      original_name = blob['filename']
      path = command[:path]
      path = BaseUtils.upload_path_base if !path || !path.length
      name = command[:name] || BaseUtils.save_fuid # do not supply extension
      thumb = command[:thumb] || nil
      # build paths
      e = File.extname(original_name).downcase # extension as in .jpg
      u = File.join path # folder to save to
      v = File.join path,name # full path - extension
      w = nil
      puts "base::save #{e} #{u} #{v} #{w}" if @@debug
      # try save
      begin
        # copy the file
        begin File.mkdir u; rescue; end;  # try make folder approach 1
        begin Dir.mkdir u; rescue; end; # try make folder approach 2 (fails?)
        #File.copy subject, "#{v}#{e}"
        handle = File.new "#{v}#{e}","w"
        return nil,"Cannot Save File to #{v}#{e}" if !handle
        str = blob['tempfile'].read
        if !str || str.length < 100
          return nil,nil
        end
        handle.write str
        handle.close
        # thumbs?
        if thumb && (e=='.jpg' || e=='.jpeg' || e=='.png' || e=='.gif' || e=='.bmp' || e=='.tif')
          # large
          img = Magick::Image.read("#{v}#{e}")
          thumb = img[0].scale(512,400)
          thumb.write File.join(u,".#{name}.large.jpg")
          # small
          # img = Magick::Image.read(v)
          thumb = img[0].scale(125,100)
          thumb.write File.join(u,".#{name}.jpg")
          # ruby needs this after using imagemagick (see google)
          GC.start
          # return the thumb path
          w = File.join "/",path,".#{name}.jpg"
        else
          w = File.join "/",path,"#{name}#{e}"
        end
      rescue
        puts "base::save exception" if @@debug
        w = nil
        return nil,"Cannot save File #{v}#{e}"
      end
      puts "base_controller::save_file() saved #{w}" if @@debug
      return w,"Image File Save"
    end

    def BaseUtils.save_from_param(elem,name,key,params)
      # save depiction if any
      if params[key] && params[key]['tempfile']
        x = save_file({:blob=>params[key],
                       :name=> name,
                       :thumb=>true
                       })
        if x
          elem[key] = x
          elem.update
        else
          #puts "base save from param failed save" if @@debug
          #flash[:warning] = "Sorry, failed to save your depiction!"
        end
      end
    end

    #########################################################################
    # utilities
    #########################################################################

	# dump all an object's attributes for inspection purposes
	# creates a div with the specified name to which it appends _# where # is the id of the object
	def BaseUtils.show_details(session,object, divname)

	    special = session[:username] &&
					   (session[:username] == "testbrad" ||
					    session[:username] == "testuser" ||
					    session[:username] == "anselm"  )

	    return '' if !object
        x = ''
		if  object && special
			x=x+ '<script>var current_status = evenodd; evenodd=true;</script>'
			x=x+ '<a href="#" class="button" onclick=\'showDiv("' + divname + '_' + object.id.to_s + '"); return false;\'>show details</a>'
			x=x+ '<div id="' + divname + '_' + object.id.to_s + '" class="db-details">'
			x=x+ '<a href="#" class="button" onclick=\'hideDiv("' + divname + '_' + object.id.to_s + '"); return false;\'>hide details</a>'
			if object.class.to_s == "Nonpros" 
				x=x+ '<a href="/catalogue/'  + object.id.to_s + '?edit=true">edit data</a>' 
			end
			x=x+ '<br><table>'
			x=x+ '<tr class="oddrow"><td><span class="db-details-fieldname">ID</span></td><td> <span class="db-details-fieldvalue">' + object.id.to_s + '</span></td></tr>'
			x=x+ '<tr class="evenrow"><td><span class="db-details-fieldname">Type</span></td><td> <span class="db-details-fieldvalue">' + object.class.to_s + '</span></td></tr>'
			object.class.new.attribute_names.each do |y|
				x=x+ '<script>evenodd = !evenodd; if (evenodd) document.write(\'<tr class="evenrow">\'); else document.write(\'<tr class="oddrow">\'); </script>'
				x=x+ '<td><span class="db-details-fieldname">' + x +'</span></td><td> <span class="db-details-fieldvalue">'
				x=x+ "#{object.send(y)}"
				x=x+ '</span> </td></tr>'
			end
			x=x+ '</table></div>'
			x=x+ '<script>hideDiv("' + divname + '_' + object.id.to_s + '"); evenodd = current_status ;</script>'
		end
  	    return x
    end

	# display a table of alternating style rows
	# takes a collection of objects, a list of column-headers space-separated, and a list of corresponding fields space-separated
	def BaseUtils.zebra_table(session,objects,headers,fields)

        return nil if !headers || !fields
	
	    special = session[:username] &&
					   (session[:username] == "testbrad" ||
					    session[:username] == "testuser" ||
					    session[:username] == "anselm"  )

        return '' if !objects
	    x = ''
		hdrs = headers.split("|")
		flds = fields.split("|")
		x=x+ '<script>var current_status = evenodd; evenodd=true;</script>'
		x=x+ '<thead>'
		hdrs.each do |hdr|
			if hdr != "Details" || special
		       x=x+ '<th>' + hdr + '</th>'
			end
		end
		x=x+ '</thead><tbody>'
		objects.each do |obj|
			objtyp = obj.class.to_s
			x=x+ '<script>evenodd = !evenodd;  if (evenodd) document.write(\'<tr class="evenrow">\'); else document.write(\'<tr class="oddrow">\'); </script>'
			flds.each do |fld| 
				if fld == "details"
				     if special
  					   x=x+ '<td valign="center" width="100px">'
  					 end
				else 
					x=x+ '<td valign="top">'
				end
				value = obj.send fld if fld != "details"
				typ = "String"
				typ = value.class.to_s if value
				if fld == "depiction" && value && value.length >1
					if objtyp == "Bookmark"
						x=x+ '<a href="/' + obj.title + '"><img src="/' + obj.title + '/.' + obj.title + '.jpg" width="80"></img></a>' 
					else
						x=x+ '<img src="' + value +'" border=0 width="40px"/>' 
					end
				elsif typ == "User"
					name = value.login
					x=x+ '<a href="/' + name + '">' + name + '</a>'
				elsif fld == "details"
					x = x + BaseUtils.show_details(session,obj, "details") 
				elsif fld == "total_donations"
					x=x+"$" if value
					x=x+value if value
				elsif fld == "name" || fld == "title" || fld == "login"
					if objtyp =="Group"
						x=x+ '<a href="/'  + obj.uid + '">' + value + '</a>' 
					elsif objtyp =="User"
						x=x+ '<a href="/'  + value + '">' + value + '</a>' 
					elsif objtyp =="Bookmark"
						x=x+ '<a href="/'  + value + '">' + value + '</a>' 
					elsif objtyp == "Nonpros" 
						x=x+ '<a href="/catalogue/'  + obj.id.to_s + '">' + value + '</a>' 
					else 
						x=x+value
					end
				else
				  x=x+value if value && !(fld == "selected" && value == "Not Selected")
				end
				x=x+ '</td>'
			end
			x=x+ '</tr>'
		end
		x=x+ '</tbody>'
		x=x+ '<script>evenodd = current_status ;</script>'
	  return x
    end

	def BaseUtils.user_pic_or_default(user_pic) 
		def_pic =  '/images/cat-glyph.gif' # @default_depiction
		def_pic = user_pic if user_pic and user_pic.length >1
		return def_pic
	end
	
  #send an email message
  def BaseUtils.send_an_email (from_name, from_email, to_email, subject, message, cc_email)
	   mess = "From:  #{from_name} <#{from_email}>\n" +
	         "To: #{to_email}\n" +
			 "CC: #{cc_email}\n" +
	         "Subject: #{subject}\n" +
	         "\n" +
	         message
	  Net::SMTP.start('localhost',25) do |smtp|
	    smtp.send_message mess,from_email,to_email
	  end
  end

end
